<template>
    <div class="article full-in-main">
        <div class="article-body">
            <div class="left-menu" v-if="showEditor === 1 && menu.length > 0">
                <h3 class="menu_header">文档目录</h3>
                <div class="menu-body">
                    <el-scrollbar style="height: 100%;width: 100%" ref="scroll">
                        <div v-for="(item, index) in menu" :key="index" @click.stop.prevent="goMenu(item)"
                            class="menu-item">
                            <div :class="`title_${item.level} menu_title ${currentItem.id === item.id ? 'current-title' : ''}`"
                                :id="`menu-${item.id}`">{{ item.text }}
                            </div>
                        </div>
                    </el-scrollbar>
                </div>

            </div>
            <div class="content" :style="`width: ${showEditor === 1 && menu.length > 0 ? '80%' : '100%'}`">
                <div v-show="showEditor === 1">
                    <h2 class="title cursor-default">{{ article.title }}</h2>
                    <div class="sub_title cursor-default">
                        <div class="note_attr">分类:{{ article.type }}</div>
                        <div class="note_attr">类型:{{ article.sourceType === 0 ? "转载" : "原创" }}</div>
                        <div class="note_attr">发布时间:{{ new Date(article.crtTime).format("YYYY-MM-DD HH:mm:ss") }}</div>
                    </div>
                    <div ref="divRef" class="article_content" @scroll.capture="scrollPage" @copy="copy" />
                </div>
                <div v-show="showEditor === 2" class="not-found">
                    <h2 class="not-found-content">文章不存在</h2>
                    <div style="display: flex;margin-top: 5px;">
                        <div class="back" @click="goHome">返回主页</div>
                        <div class="back" @click="goList">返回文章列表</div>
                    </div>
                </div>
            </div>
        </div>
        <transition name="animate__animated " enter-active-class="animate__fadeInDown animate__fast"
            leave-active-class="animate__fadeOutUp animate__faster">
            <div class="up" v-if="scrollOffsetTop > 200" @click="scrollTop">
                <svg class="up-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgba(70,146,221,1)">
                    <path
                        d="M4.99958 12.9999C4.99958 7.91198 7.90222 3.5636 11.9996 1.81799C16.0969 3.5636 18.9996 7.91198 18.9996 12.9999C18.9996 13.8229 18.9236 14.6264 18.779 15.4027L20.7194 17.2353C20.8845 17.3913 20.9238 17.6389 20.815 17.8383L18.3196 22.4133C18.1873 22.6557 17.8836 22.7451 17.6412 22.6128C17.5993 22.59 17.5608 22.5612 17.5271 22.5274L15.2925 20.2928C15.1049 20.1053 14.8506 19.9999 14.5854 19.9999H9.41379C9.14857 19.9999 8.89422 20.1053 8.70668 20.2928L6.47209 22.5274C6.27683 22.7227 5.96025 22.7227 5.76498 22.5274C5.73122 22.4937 5.70246 22.4552 5.67959 22.4133L3.18412 17.8383C3.07537 17.6389 3.11464 17.3913 3.27975 17.2353L5.22014 15.4027C5.07551 14.6264 4.99958 13.8229 4.99958 12.9999ZM6.47542 19.6957L7.29247 18.8786C7.85508 18.316 8.61814 17.9999 9.41379 17.9999H14.5854C15.381 17.9999 16.1441 18.316 16.7067 18.8786L17.5237 19.6957L18.5056 17.8955L17.4058 16.8568C16.9117 16.3901 16.6884 15.7045 16.8128 15.0364C16.9366 14.3722 16.9996 13.6911 16.9996 12.9999C16.9996 9.13037 15.0045 5.69965 11.9996 4.04033C8.99462 5.69965 6.99958 9.13037 6.99958 12.9999C6.99958 13.6911 7.06255 14.3722 7.18631 15.0364C7.31078 15.7045 7.08746 16.3901 6.59338 16.8568L5.49353 17.8955L6.47542 19.6957ZM11.9996 12.9999C10.895 12.9999 9.99958 12.1045 9.99958 10.9999C9.99958 9.89537 10.895 8.99994 11.9996 8.99994C13.1041 8.99994 13.9996 9.89537 13.9996 10.9999C13.9996 12.1045 13.1041 12.9999 11.9996 12.9999Z" />
                </svg>
            </div>
        </transition>
    </div>
</template>

<script setup>
import { AiEditor } from "aieditor"
import "aieditor/dist/style.css"
import { useRouter } from "vue-router"
import { useElMessage, useRequest, useImagePreview } from "@usehook"
import router from "@/router"

let article = $ref({
    content: "",
    crtTime: "",
    description: "",
    menu: "",
    origUrl: "",
    sequence: "",
    sourceType: 0,
    status: 1,
    title: "",
    titleImage: "",
    type: "",
    updateTime: ""
})
let showEditor = $ref(0)
let currentItem = $ref("")
let scrollOffsetTop = $ref(0)
let imageList = $ref([])

const menu = $computed(() => {
    try {
        const menu = JSON.parse(article.menu)
        currentItem = menu[0]
        return menu
    } catch (e) {
        return []
    }
})

const goHome = () => {
    router.push('/')
}

const goList = () => {
    router.push('/note')
}

const goMenu = (item) => {
    currentItem = item
    document.getElementById(item.id).scrollIntoView()
}

const scroll = $ref(null)

const refreshMenuPosition = (currentItem) => {
    document.getElementById("menu-" + currentItem.id).scrollIntoView({ behavior: "smooth" })
    const percent = (menu.indexOf(currentItem)) / menu.length
    const el = scroll.wrapRef
    if (percent > 0.2) {
        el.scrollTop = document.getElementById("menu-" + currentItem.id).offsetTop - 35;
    } else {
        el.scrollTop = 0
    }
}

const copy = (e) => {
    e.preventDefault()
    let clipboardData = e.clipboardData || window.clipboardData;
    const copyData = clipboardData.getData('text/plain').trim();
    const appendData = "\n\n————————————————————————————————————————————————————————————————————————————————————————————————\n" +
        "版权声明：本文为博主原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接和本声明。\n" +
        "原文链接：" + (article.sourceType === 0 && article.origUrl && article.origUrl.toLowerCase().startsWith("http") ? article.origUrl : window.location.href)
    clipboardData.setData('text/plain', copyData ? copyData + appendData : "")
}

const scrollTop = () => {
    document.querySelector(".aie-content").scroll({ top: 0, behavior: 'smooth' })
}

const scrollPage = (e) => {
    scrollOffsetTop = e.target.scrollTop
    if (menu.length === 0) return
    let current = menu[0]
    for (let item of menu) {
        for (let title of document.querySelectorAll("h" + item.level)) {
            if (title.id === item.id) {
                if (e.target.scrollTop + 1 >= title.offsetTop) {
                    current = item
                    break;
                }
            }
        }
    }

    if (currentItem.id !== current.id) {
        currentItem = current
        refreshMenuPosition(current)
    }
}

const divRef = $ref()

const sequence = useRouter().currentRoute.value.query.sequence

onMounted(() => {
    new AiEditor({
        element: divRef,
        placeholder: "",
        content: '',
        ai: {
            commands: []
        },
        // editable: false,
        toolbarKeys: [],
        onChange(editor) {
            document.querySelector("aie-footer span").innerText = "Characters: " + editor.getText().length
        },
        onCreated(editor) {
            document.querySelector("aie-footer span").innerText = "Characters: 0"
            document.querySelector("aie-header").remove()
            if (sequence) {
                useRequest({ url: '/article/show', sequence }).then(e => {
                    if (e && e.status) {
                        article = e.data
                        editor.setContent(e.data.content)
                        editor.setEditable(false)
                        setTimeout(() => {
                            showEditor = 1
                            const ele = document.querySelector(".aie-content")
                            if (ele) ele.scroll({ top: 0 })
                        }, 1)
                        const origUrl = e.data.origUrl
                        if (origUrl) {
                            const orig = document.createElement("span")
                            orig.classList.add("orig-url")
                            orig.innerText = "原文地址：" + origUrl
                            const footer = document.querySelector("aie-footer div")
                            footer.insertBefore(orig, footer.firstChild)
                        }

                        const el = document.querySelector(".aie-container")
                        const header = el.querySelectorAll('h1, h2, h3, h4, h5, h6')
                        let index = 1
                        for (let h of header) {
                            h.setAttribute("id", "aie-heading-" + index)
                            index += 1
                        }

                        const resizeImg = document.querySelectorAll(".aie-resize-wrapper")
                        let imgIndex = 0

                        for (let img of resizeImg) {
                            img.firstElementChild.remove()
                            img.firstElementChild.setAttribute("index", imgIndex + "")
                            img.firstElementChild.setAttribute("loading", "lazy")
                            imageList.push(img.firstElementChild.src)
                            img.addEventListener("click", (e) => {
                                useImagePreview({ url: imageList, closeOnModal: true, index: e.target.getAttribute("index") })
                            })
                            imgIndex += 1
                        }
                        const elements = document.querySelectorAll('[contenteditable]');
                        for (let element of elements) {
                            element.removeAttribute("contenteditable")
                        }
                        const expand = document.querySelectorAll('[aria-expanded]');
                        for (let element of expand) {
                            element.removeAttribute("aria-expanded")
                        }
                        const draggable = document.querySelectorAll('[draggable]');
                        for (let element of draggable) {
                            element.removeAttribute("draggable")
                        }
                        const tools = document.querySelectorAll(".aie-codeblock-tools-comments,.aie-codeblock-tools-explain")
                        for (let ele of tools) {
                            ele.remove()
                        }

                        const lang = document.querySelectorAll(".aie-codeblock-tools-lang")
                        for (let ele of lang) {
                            const span = ele.querySelector("span")
                            if (span.innerText === 'auto') {
                                ele.remove()
                            }
                            if (span.innerText === 'xml') {
                                span.innerText = 'html'
                            }
                        }

                        const code = document.querySelectorAll(".aie-codeblock-wrapper")
                        for (let ele of code) {
                            const div = document.createElement("div")
                            div.classList.add("point-tools")
                            div.innerHTML = '<div style="background: red;" class="point"></div>' +
                                '<div style="background: yellow;" class="point"></div>' +
                                '<div style="background: green;" class="point"></div>'
                            const copy = document.createElement("div")
                            copy.classList.add("copy")

                            copy.innerHTML = "<div>复制</div>"
                            const lang = ele.querySelector(".aie-codeblock-tools-lang")
                            if (lang) {
                                copy.style.right = (lang.innerText.length * 7 + 40 - lang.innerText.length * .2) + 'px'
                            } else {
                                copy.style.right = "10px"
                            }

                            function click(e) {
                                copy.onclick = null
                                navigator.clipboard.writeText(ele.querySelector("code").innerText).then(() => {
                                    e.target.classList.add('hide-copy')
                                    setTimeout(() => {
                                        e.target.classList.remove('hide-copy')
                                    }, 300)
                                }).finally(() => {
                                    setTimeout(() => {
                                        copy.onclick = click
                                    }, 2000)
                                }
                                )
                            }
                            copy.onclick = click
                            ele.insertBefore(copy, ele.firstChild)
                            ele.insertBefore(div, ele.firstChild)
                        }
                    } else {
                        useElMessage.error("文章加载失败")
                    }
                }).catch(e => {
                    if (e && e.responseCode === 404) {
                        showEditor = 2
                    }
                })
            }
        }
    })
})
</script>

<style lang="scss" scoped>
:deep(aie-footer),
:deep(aie-header) {
    div {
        border: 0 !important;
    }
}

:deep(.aie-container aie-footer) {
    div span {
        margin-top: 3px;
    }

    div {
        color: var(--font-color);
    }
}

:deep(.aie-content) {
    :first-child {
        margin-top: 0;
    }

    :last-child {
        margin-bottom: 5px;
    }
}

:deep(.article_content) {
    height: calc(100vh - 203px);

    @media screen and (max-width: 1500px) {
        height: calc(100vh - 220px);
    }

    @media screen and (min-width: 200px) and (max-width: 400px) {
        height: calc(100vh - 165px);
    }
}

:deep(.not-found) {
    position: absolute;
    left: calc(50% - 80px);
    top: calc(50% - 100px);
    height: 25px;

    @media screen and (min-width: 200px) and (max-width: 900px) {
        left: calc(50% - 58px);
    }
}

:deep(.left-menu) {
    width: 20%;
    position: relative;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        display: none;
    }
}

:deep(.content) {
    position: relative;
    padding: 0 10px;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        width: 100% !important;
        padding: 0;
    }
}

:deep(.up) {
    position: absolute;
    bottom: 30px;
    right: 10px;
    background: #99a9bf;
    border-radius: 50%;
    width: 40px;
    height: 40px;

    /*transition: all .2s;*/
    @media screen and (min-width: 200px) and (max-width: 400px) {
        right: 0;
        bottom: 0;
    }
}

:deep(aie-footer) {
    @media screen and (min-width: 200px) and (max-width: 400px) {
        display: none;
    }
}

:deep(.title) {
    cursor: default;
    height: 35px;
    display: flex;
    justify-content: center;
    align-items: center;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        margin: 10px 20px;
    }
}

:deep(.aie-codeblock-tools-comments),
:deep(.aie-codeblock-tools-explain),
:deep(#ai),
:deep(.ai-command-container hr),
:deep(aie-footer div div svg),
:deep(.aie-codeblock-tools-lang svg),
:deep(.tippy-box) {
    display: none !important;
}

:deep(.point) {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    aspect-ratio: 1;
    margin: 0 4px !important;
}

:deep(.point-tools) {
    display: flex;
    padding: 6px 10px;
    background: rgba(0, 0, 0, 0.2);
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    align-items: center;
}

:deep(.point:first-child) {
    margin-left: 0;
}

:deep(.aie-container) {
    background: transparent !important;
    border: 0 !important;
}

:deep(.aie-codeblock-tools-lang span) {
    margin-right: 10px;
    cursor: default;
}

:deep(.aie-codeblock-tools-lang) {
    cursor: default !important;
}

:deep(.aie-container .aie-codeblock-wrapper) {
    background: rgba(255, 255, 255, .5) !important;
    position: relative;
}

:deep(.aie-theme-light .hljs) {
    background: transparent !important;
    padding: 10px 15px;
}

:deep(.aie-content pre code) {
    background: transparent;
}

:deep(.aie-container img) {
    border-radius: 3px;
    border: 0;
}

:deep(.aie-content) {
    padding: 10px 10px 0 10px;

    @media screen and (min-width: 500px) {
        height: calc(100% - 10px) !important;
    }
}

:deep(.orig-url) {
    margin-left: 5px !important;
}

:deep(.sub_title) {
    align-items: center;
    padding: 0 10px 10px;
    display: flex;
    justify-content: flex-end;
    cursor: default;
    height: 24px;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        margin-top: 0;
        // display: block;
        height: 50px;
        line-height: 20px;
        flex-wrap: wrap;
        text-align: right;
    }
}

:deep(.note_attr + .note_attr) {
    padding-left: 20px;

    @media screen and (min-width: 200px) and (max-width: 400px) {
        padding: 0;
    }
}

.note_attr:nth-child(-n+2) {
    @media screen and (min-width: 200px) and (max-width: 400px) {
        min-width: 50%;
    }
}

.note_attr:last-child {
    @media screen and (min-width: 200px) and (max-width: 400px) {
        min-width: 100%;
    }
}

:deep(p code) {
    color: red;
    background: rgba(255, 255, 255, .2);
}

:deep(code),
:deep(pre),
:deep(span) {
    font-family: inherit !important;
    font-size: var(--font-size) !important;
}

:deep(.aie-resize-wrapper img:hover) {
    box-shadow: 15px 1px 15px -5px rgba(50, 50, 50, 0.4);
    /*transform: scale(1.01);*/
    /*-webkit-transform: scale(1.01);*/
    -webkit-transition: all .4s ease-in;
    -moz-transition: all .4s ease-in;
    -ms-transition: all .4s ease-in;
    -o-transition: all .4s ease-in;
    transition: all .4s ease-in;
}

:deep(.aie-resize-wrapper img) {
    -webkit-transition: all .4s ease-in;
    -moz-transition: all .4s ease-in;
    -ms-transition: all .4s ease-in;
    -o-transition: all .4s ease-in;
    transition: all .4s ease-in;
}

:deep(.article-body) {
    display: flex;
    width: 100%;
    height: 100%;
}

:deep(.menu_header) {
    margin: 20px 10px 15px 20px;
}

:deep(.menu-body) {
    height: calc(100% - 70px);
    max-width: calc(85% - 10px);
    margin: 0 10px;
    overflow: hidden;
    /*background: rgba(0, 0, 0, .3);*/
    box-shadow: 1px 1px 10px -5px #7a7575;
    padding: 5px;
    border-radius: var(--border-radius);
    position: relative;
}

:deep(.menu-item) {
    padding: 2px 0;
    transition: all .3s ease-in-out;
    margin-left: 10px;
}

:deep(.title_3) {
    margin-left: 30px;
}

:deep(.title_4) {
    margin-left: 60px;
}

:deep(.title_5) {
    margin-left: 80px;
}

:deep(.current-title) {
    background: rgba(231, 231, 231, .3);
    border-radius: var(--border-radius);
    padding: 5px;
    animation: moveOut 1s forwards !important;
    transition: background-color 1s ease-out;
}

@keyframes moveOut {
    0% {
        transform: translateX(0);
    }

    100% {
        transform: translateX(-5px);
    }
}

:deep(.menu_title) {
    padding: 5px 10px;
    animation: moveIn 1s forwards;
    opacity: 1;
    border-radius: var(--border-radius);
    transition: background-color 1s ease-in-out;
}

@keyframes moveIn {
    0% {
        transform: translateX(-5px);
    }

    100% {
        transform: translateX(0);
    }
}

:deep(.copy) {
    position: absolute;
    top: 6px;
    font-size: 13px;
}

:deep(.copy>div) {
    margin: 0 !important;
}

:deep(.menu-item:hover) {
    /*background: rgba(120, 120, 120, .8);*/
    transform: translateX(2px) translateY(2px);
    color: #409eff;
    transition: all .3s ease-in-out;
    border-radius: var(--border-radius);
}

:deep(.aie-content pre) {
    padding: 5px 10px;
}

:deep(.aie-codeblock-tools) {
    position: absolute;
    top: 3px;
    right: 5px;
}

:deep(.aie-container .aie-codeblock-wrapper) {
    margin: 10px 0;
    padding-top: 0;
}

:deep(.el-scrollbar__bar.is-vertical) {
    width: 0 !important;
}

:deep(.fade-transform-enter),
:deep(.fade-transform-leave-to) {
    opacity: 0;
    transform: translateX(30px);
}

:deep(.not-found-content) {
    text-align: center;
    color: #b33939;
    cursor: default;
    font-size: 25px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
}

:deep(.back) {
    display: flex;
    align-items: flex-end;
    margin-left: 10px;
    cursor: pointer;
    text-decoration: underline;
}

:deep(.back:first-child) {
    margin-left: 0;
}

:deep(.up-arrow) {
    width: 30px;
    height: 30px;
    padding: 5px;
}

:deep(.aie-content h1) {
    padding-top: 0;
}

:deep(.aie-content h2) {
    text-align: left;
    justify-content: flex-start;
    padding-top: 0;
    font-size: calc(var(--font-size) + 5px);
}

:deep(.aie-content h3) {
    font-size: calc(var(--font-size) + 4px);
    padding-top: 0;
    margin: 20px 0;
}

:deep(.aie-content h4) {
    font-size: calc(var(--font-size) + 3px);
    padding-top: 0;
}

:deep(.aie-content h5) {
    font-size: calc(var(--font-size) + 2px);
    padding-top: 0;
}

:deep(img) {
    max-width: 100%;
    width: 100% !important;
}

:deep(.el-image-viewer__canvas img) {
    width: auto !important;
}

:deep(.aie-content blockquote) {
    border-radius: 5px;
    background: rgba(255, 255, 255, .5);
    border-left: 2px solid #ffa0a0;
}

:deep(.ProseMirror) {
    white-space: inherit;
}

:deep(.hide-copy) {
    opacity: 0 !important;
    transition: all 200ms ease-out;
}

:deep(.show-copy) {
    opacity: 1;
    transition: all 500ms ease-out;
}

:deep(.el-scrollbar__bar.is-horizontal) {
    height: 0;
}

.article {
    position: relative;
}

:deep(hr) {
    border: 0;
}

:deep(h2) {
    margin: 20px;
}

:deep(.aie-content) {
    color: var(--font-color);
}

:deep(.aie-content div.warning) {
    padding: 10px 20px;
}

:deep(.aie-container .aie-content .selection-marker) {
    padding: 0;
}
</style>